func findMaxForm(strs []string, m int, n int) int {
    /*
        力扣 474. 一和零

        01背包问题

        1. dp 数组含义
            dp[i][j] 表示 i个0的和j个1可以包含的最大子集的数量

        2. dp递推公式
            遍历到的物品的当前的   0 的数量为 zeroNum
                                   1 的数量为 oneNum
            dp[i][j] = dp[i-zeroNum][j - onwNum] + 1

            采用覆盖式写法：
                dp[i][j] = max(dp[i][j], dp[i-zeroNum][j-oneNum])

        3. 初始化dp数组
            dp[0][0] = 0

        4. 确定遍历顺序
            由于时覆盖写法，背包容量需要从后往前遍历

        5. 递推出dp数组    
    */

    dp := make([][]int, m+1)
    for i:=0; i<len(dp); i++ {
        dp[i] = make([]int, n+1)
    }
    for _, str := range strs {
        zeroNum := 0
        oneNum := 0
        for _, v := range str {
            if v == '0' {
                zeroNum++
            }
        }
        oneNum = len(str) - zeroNum
        
        for i:= m; i>=zeroNum; i--{
            for j:=n; j>=oneNum; j-- {
                dp[i][j] = max(dp[i][j], dp[i-zeroNum][j-oneNum]+1)
            }
        }
    }
    return dp[m][n]
}

func max(a, b int) int {
    if a > b {
        return a
    }
    return b
}